var geoService = require('../../services/geoService'),
    idService = require('../../services/idService'),
    utils = require('../../helpers/utils'),
    mongoose = require('mongoose'),
    nodeunit = require('nodeunit');

var point = {
        type: 'FeatureCollection',
        features: [
            {
                type: 'Feature',
                geometry: {
                    type: 'Point',
                    coordinates: [4.0, -3.0]
                }
            }
        ]
    },
    polygon = {
        type: 'FeatureCollection',
        features: [
            {
                type: 'Feature',
                geometry: {
                    type: 'Polygon',
                    coordinates: [
                        [ [4.0, -3.0],
                          [4.0, 3.0],
                          [-4.0, 3.0],
                          [-4.0, 3.0],
                          [4.0, -3.0]
                        ]
                    ]
                }
            }
        ]
    },
    originalId,
    updateId,
    removeId;

exports['geos'] = nodeunit.testCase({
    'initialize' : function (test) {
        test.doesNotThrow(
            function() {
                idService.initializeModelId('geos', function(resp) {
                    idService.getId('geos', function(id){
                        originalId = id;
                    });
                });
            }
        );
        setTimeout(test.done, 500);
    },
    'set1' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.set(point, function(geo) {
                    test.ok(geo, 'Set1 responde');
                    test.equal(geo.features[0].geometry.type, 'Point', 'Se insertó un punto');
                    test.ok(geo.id, 'Set1 ID insertado');
                    updateId = geo.id;
                });
            }
        );
        setTimeout(test.done, 500);
    },
    'set2' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.set(polygon, function(geo) {
                    test.ok(geo, 'Set2 responde');
                    test.equal(geo.features[0].geometry.type, 'Polygon', 'Se insertó un polígono');
                    test.ok(geo.id, 'Set2 ID insertado');
                    removeId = geo.id;
                });
            }
        );
        setTimeout(test.done, 500);
    },
    'getAll' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.getAll(false, function(geos){
                    test.ok(geos, 'Short False: recuperé todos los geos');
                    geos.forEach(function(geo) {
                        test.ok(geo, 'Short False: geo OK');
                        test.ok(geo.id, 'Short False: ID recuperado');
                        test.ok(geo.type, 'Short False: type recuperado');
                        test.ok(geo.features, 'Short False: Features recuperados');
                        test.ok(geo.geospatial, 'Short False: geospatial recuperado');
                    });
                    geoService.getAll(true, function(geos){
                        test.ok(geos, 'Short True: recuperé todos los geos');
                        geos.forEach(function(geo) {
                            test.ok(geo, 'Short True: geo OK');
                            test.ok(geo.id, 'Short True: ID recuperado');
                        });
                    });
                });
            }
        );
        setTimeout(test.done, 1000);
    },
    'find' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.find({type: point.type}, function(geos){
                    test.ok(geos, 'recuperé geos');
                    test.equal(geos.length, 2, 'Recupere 2 geos');
                    geos.forEach(function(geo) {
                        test.equal(geo.type, point.type, 'type OK');
                    });
                });
            }
        );
        setTimeout(test.done, 1000);
    },
    'findOne' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.findOne({id: updateId}, function(geo){
                    test.ok(geo, 'recuperé geo insertado');
                    test.ok(geo.id, 'Id autogenerado: ' + geo.id);
                    console.log("geoid: " + geo.id + " updateId: " + updateId);
                    test.equal(geo.id, updateId, 'id OK');
                });
            }
        );
        setTimeout(test.done, 1000);
    },
    'update' : function (test) {
        test.doesNotThrow(
            function() {
                point.features[0].geometry.coordinates = [5.0, -5.0];
                point.id = updateId;
                geoService.update(point.id, point, function(resp) {
                    geoService.findOne({id: point.id}, function(geo) {
                        test.ok(geo, 'Recupere geo actualizado');
                        test.equal(geo.features[0].geometry.coordinates[0], 5.0, 'Coordinada actualizada');
                        test.equal(geo.features[0].geometry.coordinates[1], -5.0, 'Coordinada actualizada');
                    });
                });
            }
        );
        setTimeout(test.done, 1000);
    },
    'remove' : function (test) {
        test.doesNotThrow(
            function() {
                geoService.remove(updateId, function(resp) {
                    geoService.findOne({id: updateId}, function(geo) {
                        test.equal(geo, null, 'geo eliminado');
                    });
                });
            }
        );
        setTimeout(test.done, 1000);
    },
    'done': function(test) {
        geoService.remove(removeId, function(resp) {});
        idService.upsert('geos', {$set: { nextId: originalId} }, function(){
                mongoose.disconnect();
                test.done();
        });
    }
});